/*
<license>
This software is distributed under the Simplified BSD License:

Copyright (c) 2008, Chris Venter <chris.venter@gmail.com>
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright notice,
    	this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright notice,
    	this list of conditions and the following disclaimer in the documentation
    	and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
</license>
*/
#ifndef GENERIK_MACROS_H
#define GENERIK_MACROS_H

/** \file macros.h This file defines a couple of general purpose macros.

 All of the generik macros are prepended with GENERIK_, in order to try
 and minimise the impact on the global namespace.

*/

/**
\def GENERIK_PASTE_TEST_(X)
This is a utility-utility macro which pastes its argument as text.
*/
#define GENERIK_PASTE_TEXT_(X)	#X

/**
\def GENERIK_PASTE_TEXT(X)
This is a utility macro which pastes its argument as text.
It thunks through to the GENERIK_PASTE_TEXT_ macro which does the actual
work. This is necessary since using __LINE__ with this macro will not
work directly.
*/
#define GENERIK_PASTE_TEXT(X)	GENERIK_PASTE_TEXT_(X)

/**
\def GENERIK_FILE_LINE
A short-cut macro which evaluates to a string representing the filename
and line where it is used.
The string is in the form "<filename>@linenumber".
It generates the filename from the __FILE__ macro, which is generated
by the compiler as it processes source code, ie. it is not a true macro,
but acts like one which continually changes value.
The linenumber is similar, except that it is a numeric literal.
To get it into string form therefore requires some macro magic, which is
performed by the GENERIK_PASTE_TEXT macro.
*/
#define GENERIK_FILE_LINE	__FILE__ "@" GENERIK_PASTE_TEXT(__LINE__)

//#define GENERIK_FUNC_FILE_LINE	GENERIK_PASTE_TEXT(__PRETTY_FUNCTION__) ":" GENERIK_FILE_LINE

/**
\def GENERIK_LINENAME
A short-cut macro which generates a variable name by concatenating the 
calling line number to the specified "name" parameter.
This may be used to auto generate unique variable names easily.

From Gamedev discussion: "Variable name from __LINE__"
http://www.gamedev.net/community/forums/topic.asp?topic_id=87083
*/
#define GENERIK_LINENAME_CAT_( name, line ) name##line
#define GENERIK_LINENAME_( name, line ) GENERIK_LINENAME_CAT_( name, line )
#define GENERIK_LINENAME( name ) GENERIK_LINENAME_( name, __LINE__ )

/**
\def GENERIK_FOR_EACH(VALUE, CONTAINER)
This is a utility macro, to quickly construct a for-loop which will iterate over
all the values in a CONTAINER.
For each iteration of the loop, VALUE becomes the iterator that points to the next
item in the CONTAINER.

It uses __typeof__ magic to determine the iterator-type from the CONTAINER itself.

\note This will *only* work for CONTAINERS that define begin() and end() methods,
where begin() evaluates to an forward iterator and end() evaluates to one element
past the end of the CONTAINER. This is the paradigm which is used by most of the 
STL containers.

It is a dirty hack, mixing the GNU typeof extension with macro magik, but IMHO
it is worth it, simply because it does not obscure the meaning of code
which uses it (ie. it is not a deep macro) and actually makes the code easier
to maintain, understand, check and (above all) use!

\note It uses the GENERIK_LINENAME(name) macro to define a temporary variable
to store the end of the sequence in. The macro ensures that the variable is 
unique, so that the GENERIK_FOR_EACH macro may be used multiple times within the
same scope, or even in nested scopes, without name clashes.
*/
#define GENERIK_FOR_EACH(INDEX, CONTAINER) \
	typeof(CONTAINER.begin()) GENERIK_LINENAME(END) = CONTAINER.end(); \
	for (typeof(CONTAINER.begin()) INDEX = CONTAINER.begin(); INDEX != GENERIK_LINENAME(END); ++INDEX)

//#define GENERIK_FOR_EACH(VALUE, CONTAINER) for(__typeof__(CONTAINER.begin()) VALUE = CONTAINER.begin(); VALUE != CONTAINER.end(); ++VALUE)

#endif






